# coding:utf8
import random

import cv2
import numpy as np
coopbl = r"D:\hiicy\documents\COOPBL.ttf"
msyh = r"D:\hiicy\documents\msyh.ttf"
msyhbd = r"D:\hiicy\documents\msyhbd.ttf"
simsun = r"D:\hiicy\documents\simsun.ttf"
STSONG = r"D:\hiicy\documents\STSONG.ttf"
fonts = [
    coopbl,
    msyh,
    msyhbd,
    simsun,
    STSONG
]
import re
def build_dict(file):
    """

    :param file:
    :return:
    {字：ID}
    """
    with open(file,'r',encoding='utf8') as fi:
        # REW:
        text = fi.readline().replace(''," ").strip()
        label_dict = {}
        for index,char in enumerate(text.split()[1:]):
                label_dict[char] = str(index).zfill(5)
    return label_dict
char_path = r'D:\hiicy\demad\train_chars.txt'
build_dict(char_path)

def rotate_angles(rotate):
    """
    关于字的旋转角度
    :param rotate:
    :return:
    """
    if rotate < 0:
        rotate = -rotate
    rotate_sep = random.randint(3,8)
    rotate_angles_list = []
    if rotate > 0 and rotate < 45:
        # 正角度
        for angle in range(0,rotate,rotate_sep):
            rotate_angles_list.append(angle)
        # 负角度
        for angle in range(-rotate,0,-rotate_sep):
            rotate_angles_list.append(angle)
    return rotate_angles_list
from PIL import ImageDraw, Image, ImageFont

# 寻找字体最小矩形
class FindImageBBox(object):
    def __init__(self):
        pass

    def do(self,img):
        heigth = img.shape[1]
        width = img.shape[0]
        v_sum = np.sum(img,axis=0) # 一列列的和，不为0，存在值
        h_sum = np.sum(img,axis=1) # 一行行的和
        left = 0
        top = 0
        right = width - 1
        bottom = heigth - 1
        for i in range(width):# 从左到右
            if v_sum[i] > 0:
                left = i
        for i in range(width-1,0,-1):  # 从左到右
            if v_sum[i] > 0:
                right = i
        for i in range(heigth):  # 从左到右
            if h_sum[i] > 0:
                top = i
        for i in range(heigth-1,0,-1):
            if h_sum[i] > 0:
                bottom = i
        return (left,right,top,bottom)

    # 对字体图像做等比例缩放
class PreprocessResizeKeepRatio(object):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def do(self, cv2_img):
        max_width = self.width
        max_height = self.height
        cur_height, cur_width = cv2_img.shape[:2]
        ratio_w = float(max_width) / float(cur_width)
        ratio_h = float(max_height) / float(cur_height)
        ratio = min(ratio_w, ratio_h)
        new_size = (min(int(cur_width * ratio), max_width),
                    min(int(cur_height * ratio), max_height))
        new_size = (max(new_size[0], 1),
                    max(new_size[1], 1),)
        resized_img = cv2.resize(cv2_img, new_size)
        return resized_img


# 把字体图像放到背景图像中
class PreprocessResizeKeepRatioFillBG(object):
    def __init__(self, width, height,
                 fill_bg=False,
                 auto_avoid_fill_bg=True,
                 margin=None):
        self.width = width
        self.height = height
        self.fill_bg = fill_bg
        self.auto_avoid_fill_bg = auto_avoid_fill_bg
        self.margin = margin

    @classmethod
    def is_need_fill_bg(cls, cv2_img, th=0.5, max_val=255):
        height, width = cv2_img.shape

        if height * 3 < width:
            return True
        if width * 3 < height:
            return True
        return False

    @classmethod
    def put_img_into_center(cls, img_large, img_small,):
        width_large = img_large.shape[1]
        height_large = img_large.shape[0]
        width_small = img_small.shape[1]
        height_small = img_small.shape[0]
        if width_large < width_small:
            raise ValueError("width_large <= width_small")
        if height_large < height_small:
            raise ValueError("height_large <= height_small")
        start_width = (width_large - width_small) / 2
        start_height = (height_large - height_small) / 2
        img_large[start_height:start_height + height_small,
        start_width:start_width + width_small] = img_small
        return img_large

    def do(self, cv2_img):
        # 确定有效字体区域，原图减去边缘长度就是字体的区域
        if self.margin is not None:
            width_minus_margin = max(2, self.width - self.margin)
            height_minus_margin = max(2, self.height - self.margin)
        else:
            width_minus_margin = self.width
            height_minus_margin = self.height
        cur_height, cur_width = cv2_img.shape[:2]
        if len(cv2_img.shape) > 2:
            # 像素维度
            pix_dim = cv2_img.shape[2]
        else:
            pix_dim = None
        preprocess_resize_keep_ratio = PreprocessResizeKeepRatio(
            width_minus_margin,
            height_minus_margin)
        resized_cv2_img = preprocess_resize_keep_ratio.do(cv2_img)
        if self.auto_avoid_fill_bg:
            need_fill_bg = self.is_need_fill_bg(cv2_img)
            # 填充背景
            if not need_fill_bg:
                self.fill_bg = False
            else:
                self.fill_bg = True

        #should skip horizontal stroke
        if not self.fill_bg:
            ret_img = cv2.resize(resized_cv2_img, (width_minus_margin,
                                                   height_minus_margin))
        else:
            if pix_dim is not None:
                norm_img = np.zeros((height_minus_margin,
                                     width_minus_margin,
                                     pix_dim),
                                    np.uint8)
            else:
                norm_img = np.zeros((height_minus_margin,
                                     width_minus_margin),
                                    np.uint8)
            # 将缩放后的字体图像置于背景图像中央
            ret_img = self.put_img_into_center(norm_img, resized_cv2_img)
        if self.margin is not None:
            if pix_dim is not None:
                norm_img = np.zeros((self.height,
                                     self.width,
                                     pix_dim),
                                    np.uint8)
            else:
                norm_img = np.zeros((self.height,
                                     self.width),
                                    np.uint8)
            ret_img = self.put_img_into_center(norm_img, ret_img)
        return ret_img

# 不是坐标是图片大小
def draw_alpha(char_dict,width=24,height=24,margin=None,need_crop=None):
    font_path=random.choice(fonts)
    def Do(font_path,char,rotate):
        find_image_bbox = FindImageBBox()
        img = Image.new("RGB",(width,height))
        draw = ImageDraw.Draw(img)
        font = ImageFont.truetype(font_path)
        draw.text((0,0),char,(255,255,255),font)
        if rotate !=0:
            img = img.rotate(rotate)
        left,right,top,bottom = find_image_bbox.do(img) or img.getbbox()
        data = list(img.getdata())
        sum_val = 0
        for line_data in data:
            sum_val += line_data
        if sum_val > 2:
            np_img = np.asarray(data, dtype='uint8')
            np_img = np_img[:, 0]
            np_img = np_img.reshape((height,width))
            cropped_box = find_image_bbox.do(np_img)
            left, upper, right, lower = cropped_box
            np_img = np_img[upper: lower + 1, left: right + 1]
            if not need_crop:
                preprocess_resize_keep_ratio_fill_bg = \
                    PreprocessResizeKeepRatioFillBG(width, height,
                                                    fill_bg=False,
                                                    margin=margin)
                np_img = preprocess_resize_keep_ratio_fill_bg.do(
                    np_img)
            # cv2.imwrite(path_img, np_img)
            return np_img
        else:
            print("img doesn't exist.")


